package cn.tedu.tmall.admin.mall.service.impl;

import cn.tedu.tmall.admin.mall.dao.persist.repository.ICategoryRepository;
import cn.tedu.tmall.admin.mall.dao.persist.repository.IGoodsDetailRepository;
import cn.tedu.tmall.admin.mall.dao.persist.repository.IGoodsRepository;
import cn.tedu.tmall.admin.mall.dao.persist.repository.impl.GoodsRepositoryImpl;
import cn.tedu.tmall.admin.mall.dao.search.IGoodsSearchRepository;
import cn.tedu.tmall.admin.mall.pojo.entity.Goods;
import cn.tedu.tmall.admin.mall.pojo.entity.GoodsDetail;
import cn.tedu.tmall.admin.mall.pojo.param.GoodsAddNewParam;
import cn.tedu.tmall.admin.mall.pojo.vo.CategoryStandardVO;
import cn.tedu.tmall.admin.mall.pojo.vo.GoodsListItemVO;
import cn.tedu.tmall.admin.mall.pojo.vo.GoodsStandardVO;
import cn.tedu.tmall.admin.mall.service.IGoodsService;
import cn.tedu.tmall.common.enumerator.ServiceCode;
import cn.tedu.tmall.common.ex.ServiceException;
import cn.tedu.tmall.common.pojo.authentication.CurrentPrincipal;
import cn.tedu.tmall.common.pojo.po.GoodsSearchPO;
import cn.tedu.tmall.common.pojo.vo.PageData;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class GoodsServiceImpl implements IGoodsService {
    @Autowired
    private IGoodsRepository goodsRepository;
    @Autowired
    private ICategoryRepository categoryRepository;
    @Autowired
    private IGoodsDetailRepository goodsDetailRepository;
    @Autowired
    private IGoodsSearchRepository goodsSearchRepository;

    @Override
    public GoodsStandardVO getStandardById(Long id) {
        GoodsStandardVO queryResult = goodsRepository.getStandardById(id);
        if (queryResult == null) {
            String message = "获取类别详情失败,尝试访问的数据不存在!";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND,message);
        }
        return queryResult;
    }

    @Override
    public void addNew(CurrentPrincipal currentPrincipal, GoodsAddNewParam goodsAddNewParam) {
        // 发布商品核心逻辑
        // -- 如果类别不存在，不允许发布
        // -- 如果类别包含子级，不允许发布
        // -- 如果类别被禁用，不允许发布
        Long categoryId = goodsAddNewParam.getCategoryId();
        CategoryStandardVO category = categoryRepository.getStandardById(categoryId);
        if (category == null) {
            String message = "发布商品失败,类别数据不存在!";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND,message);
        }

        if (category.getIsParent() != 0) {
            String message = "发布商品失败,选择的类别必须不包含子级类别";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT,message);
        }

        if (category.getEnable() == 0) {
            String message = "发布商品失败,选择的类别已经被禁用";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT,message);
        }

        Goods goods = new Goods();
        BeanUtils.copyProperties(goodsAddNewParam,goods);
        goods.setCategoryName(category.getName());
        goods.setSalesCount(0);
        goods.setCommentCount(0);
        goods.setPositiveCommentCount(0);
        goods.setNegativeCommentCount(0);
        int rows = goodsRepository.insert(goods);
        if (rows != 1) {
            String message = "发布商品失败,服务器忙,请稍后在尝试!";
            throw new ServiceException(ServiceCode.ERROR_INSERT,message);
        }

        GoodsDetail goodsDetail = new GoodsDetail();
        goodsDetail.setGoodsId(goods.getId());
        goodsDetail.setDetail(goodsAddNewParam.getDetail());
        rows = goodsDetailRepository.insert(goodsDetail);
        if (rows != 1){
            String message = "发布商品失败,服务器忙,请稍后在尝试!";
            throw new ServiceException(ServiceCode.ERROR_INSERT,message);
        }
    }

    @Override
    public void passCheck(CurrentPrincipal currentPrincipal, Long goodsId, String remarks) {
        // 核心逻辑请参考调用的私有方法
        updateCheckById(currentPrincipal,goodsId,CHECK_STATE_PASS,remarks);
    }

    @Override
    public void rejectCheck(CurrentPrincipal currentPrincipal, Long goodsId, String remarks) {
        updateCheckById(currentPrincipal,goodsId,CHECK_STATE_REJECT,remarks);
    }

    @Override
    public void putOn(CurrentPrincipal currentPrincipal, Long id) {
        // 核心逻辑请参考调用的私有方法

    }

    @Override
    public void pullOff(CurrentPrincipal currentPrincipal, Long id) {

    }

    @Override
    public PageData<GoodsListItemVO> list(Integer pageNum, Integer pageSize) {
        return goodsRepository.list(pageNum,pageSize);
    }

    @Override
    public PageData<GoodsListItemVO> listByCategory(Long categoryId, Integer pageNum, Integer pageSize) {
        return goodsRepository.listByCategory(categoryId, pageNum, pageSize);
    }

    @Override
    public void rebuildSearch() {
        goodsSearchRepository.deleteAll();
        Integer pageNum = 1;
        Integer pageSize = 3;
        Integer maxPage;
        PageData<GoodsSearchPO> pageData;
        do {
            pageData= goodsRepository.listSearch(pageNum, pageSize);
            maxPage = pageData.getMaxPage();
            List<GoodsSearchPO> list = pageData.getList();
            goodsSearchRepository.saveAll(list);
            pageNum++;
        } while (pageNum <= maxPage);
    }

    /**
     *
     *
     * @param currentPrincipal
     * @param id
     * @param checkState
     * @param remarks
     */
    private void updateCheckById(CurrentPrincipal currentPrincipal,Long id,Integer checkState, String remarks) {
        // 修改商品的审核状态核心逻辑
        // -- 如果商品不存在，不允许修改
        GoodsStandardVO currentGoods = goodsRepository.getStandardById(id);
        if (currentGoods == null) {
            String message = "将商品的审核状态改为【" + CHECK_STATE_TEXT[checkState] + "】失败,商品数据不存在!";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND,message);
        }

        // -- 如果目标状态与当前状态相同，不允许修改
        if (currentGoods.getCheckState().equals(checkState)) {
            String message = "将商品的审核状态修改为【" + CHECK_STATE_TEXT[checkState] +"】失败,此商品已经处于" + CHECK_STATE_TEXT[checkState] + "状态!";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT,message);
        }

        Goods updateGoods = new Goods();
        updateGoods.setId(id);
        updateGoods.setCheckState(checkState);
        int rows = goodsRepository.updateById(updateGoods);
        if (rows != 1) {
            String message = "将商品的审核状态修改为【" + CHECK_STATE_TEXT[checkState] + "】失败,服务器忙,请稍后再试!";
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }

        if (checkState == CHECK_STATE_PASS) {
            GoodsSearchPO goodsSearchPO = new GoodsSearchPO();
            BeanUtils.copyProperties(currentGoods,goodsSearchPO);
            goodsSearchRepository.save(goodsSearchPO);
        }
    }

    private void updatePutOnById(Long id, Integer putOnState) {
        // 修改商品的上架状态核心逻辑
        // -- 如果商品不存在，不允许修改

        GoodsStandardVO currentGoods = goodsRepository.getStandardById(id);
        if (currentGoods == null) {
            String message = "将商品状态修改为【" + PUT_ON_STATE_TEXT[putOnState] + "】失败,商品数据不存在!";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND,message);
        }

        // -- 如果目标状态与当前状态相同，不允许修改
        if (currentGoods.getIsPutOn().equals(putOnState)) {
            String message = "将商品状态修改为【" + PUT_ON_STATE_TEXT[putOnState] + "】失败,此商品尚未通过审核!";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT,message);
        }

        // -- 如果商品不是“通过审核”状态，不允许修改
        if (!currentGoods.getCheckState().equals(CHECK_STATE_PASS)) {
            String message = "将商品状态修改为【" + PUT_ON_STATE_TEXT[putOnState] + "】失败,此商品尚未通过审核!";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT,message);
        }

        Goods updateGoods = new Goods();
        updateGoods.setId(id);
        updateGoods.setIsPutOn(putOnState);

        // -- 如果下架，将推荐状态改为“不推荐”
        if (putOnState == PUT_ON_STATE_OFF) {
            updateGoods.setIsRecommend(RECOMMEND_STATE_OFF);
        }

        int rows = goodsRepository.updateById(updateGoods);
        if (rows != 1) {
            String message = "将商品的审核状态修改为【" + PUT_ON_STATE_TEXT[putOnState] + "】失败,服务器忙,请稍后再试!";
            throw new ServiceException(ServiceCode.ERROR_UPDATE,message);
        }

    }
}
